home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-12-11 | 10.7 KB | 189 lines | [TEXT/MPS ] |
- The Clipboard Magician would look for components in the file 'Magic Wand'.
- The components are of the resource type 'CNVT', the resource name must follow
- certain naming convention so that CM understands its content. The first four
- characters of the resource name is the data type that the component can work on.
- So if the scrap data of type 'ICON' is selected, CM would look for all 'CNVT'
- resources with names that start with 'ICON' and displayed them to the user.
- '****' is used as the wildcard name, so any component with resource name starting
- with '****' is always presented to the user if some scrap data type is selected.
- '____' is used to indicate null data where no scrap data is selected. This is
- for the components that does not need any input data, but would generate new data
- on its own. The rest of the resource name is just the name of the component.
- THe component that converts one data type to another has a special naming
- convention. The resource name would have a '>' as the fifth character,
- followed by new data type name. So the component to convert an 'ICON' to 'PICT'
- would have the name 'ICON>PICT'.
-
- The basic model is that each component is a tool for data transformation, a pipe
- where certain type of data goes in at one end, and the transformed data comes
- out at the other end. The component is not aware that it is processing scrap data.
- In fact the components need not be used in the CM environment. I choose the
- CM environment because I want to prove it can be done in a very small program.
- It can be a much more powerful system if it is put in a richer environment.
- The input to the component is the input data type, the input data handle, and
- the component would return the output data type and the output data handle.
- The 'CNVT' is just a code resource with the entry point at the beginning.
-
- INTERFACE
- TYPE
- RoutineInfo = RECORD
- entryPoint: ProcPtr;
- resID: Integer;
- parmCount: Integer;
- useDefault: Boolean;
- END;
- RoutineInfoPtr = ^RoutineInfo;
- ParmInfo = RECORD
- srcType: ResType;
- srcHandle: Handle;
- dstType: ResType;
- dstHandle: Handle;
- { more if necessary }
- END;
- ParmInfoPtr = ^ParmInfo;
-
- FUNCTION ExtRoutine(myInfoPtr: RoutineInfoPtr; parmPtr:parmInfoPtr):OSErr;
-
- SrcType and srcHandle is the input to the component. The component returns the
- data in dstHandle (initialized to NIL before it is called) and type in dstType.
- The function returns NoErr if the conversion is successful, otherwise it
- returns an error code. If the operation is successful but no data handle is
- generated (as in the case where the component just prints the data), then it
- should return a NoErr but leaves the dstHandle as NIL.
-
- The RoutineInfo supplies some information that may be useful. ResID is the
- resource ID of this code resource. Since a component may need to own resource,
- the convention is that an ID range of 32 is assigned to the component. It can
- find out its own ID so that it can deduce the ID of the owned resources.
-
- ParmCount is the number of parameters in ParmInfo. Right now it is always 4.
- It is put here because it may be possible to use the 'CNVT' components in a
- non-CM environment, and then it may be possible to have extra parameters. For
- example a text printing module may accept extra parameter as the font and size,
- and uses default font and size when parmCount = 4 because no extra parameter
- is supplied.
-
- UseDefault means whether to use the default value or to ask the user about it.
- In the CM environment UseDefault is false if the command was evoked with the
- option key down. So in the text printing module, if UseDefault is true, the
- text is printed with certain font and size, if it is false, a font dialog is
- used to let the user choose the value.
-
- EntryPoint is the address provided to call other components. If the component
- wish to call another component, then it should define the following function
-
- Function GoExec(rtnRsrc: ResType; NamePtr:StrintPtr; parmCount:Integer;
- useDefault:Boolean; parmPtr:Ptr; entryPoint:ProcPtr):
- OSErr; INLINE $205F, $4E90; {move.l (A7)+, A0; JSR (A0)}
-
- RtnRsrc is the resource type of the component, normally it is 'CNVT'.
- 'CNVT' resource is visible to the user and will be executed by the user,
- If you want to write a component that is shared by several components and yet
- not visible to the user, you can put them into 'XRTN' resources. 'XRTN'
- resource are like 'CNVT' except there is no naming convention and you
- decide what the parmaters are. NamePtr is the name of the componet you want
- to call. If you are calling a 'CNVT' component, do not forget that there are
- four letters in the front. parmCount, useDefault has the usual meaning.
- You make up your own parameter list and use parmPtr to point to it. Remember
- that if you are calling a XRTN, then the parameter record no longer need to
- be of the type ParmInfo, that is why parmPtr is a Ptr rather than a ParmInfoPtr.
- entryPoint is just the address provided in routineInfo and GoExec just jsr to it.
- Also noted that the call may be to an external routine as well as to an
- internal routine since it is up to the dispatcher in CM. However, the current
- implementation of CM has no internal call back routine so all calls would be
- dispatched to external components.
-
- 'CNVT' component may have a resource 'CNV!' with the same ID and the same data
- format as 'STR ', the string is a simple description of the component and
- will be displayed when the user choose "About this command" from the menu.
-
- ******************************************************************************
-
- In version 0.55, you may return a data type name 'scrp' which has the same format
- as scrap data, i.e. Type name followed by long word data length, followed by the
- data padded to even bytes, then the next type etc. The DA would break up the data
- and put all of them on to the scrap. Be aware of the fact the specification of the
- clipboard magician still need improvement and expect such evolutionary changes in the
- future.
-
- I have also included a sample program to show how a convertor looks like. For
- those of you working with Think Pascal, I have also include a simulator that
- let you dubug a CNVT code resource as an ordinray routine rather than as a code
- resource so that you can use all the dubug facilites of Think. This is like the DA
- shell in Think. In fact all the components release after version 0.5 are written this way.
- There are two constants you need to specify for every new CNVT that you are going to
- write. The first is the type of data it can handle (resource name/****/____). If you
- intend to use resources you also need to specify the resource base ID.
- If you intend to call other code resources you should make a copy of the Magic Wand
- and use that file as your resource file in your development process. You may use the
- Magic Wand file directly if you do not intend to call up the Clipboard Magican DA
- during your debug process. However my own experience is that it is useful to be able
- to call up the DA. The simulator is for testing purpose and does not operates like
- the DA. Here the components do not work on the data from the scrap directly. The
- program maintains a list of data objects (which you can cut/copy/paste to the scrap),
- the component will work on the data object selected and the result will be added to
- the list of data objects.
-
- *****************************************************************************
-
- Starting from version 0.61, there are a number of changes.
- First, there is no longer a 'XRTN' type of resource. If you want a CNVT that is not
- visiable to the user, give it the datatype of ' ', since there is no such datatype
- it would be not be visiable.
- The meaning of parmCount has been changed slightly, now a ResType and the data handle
- together is treated as one parameter and every parameter must be of that form, i.e. typed.
- So most of the time expect a parmCount of 2.
- It was mentioned in the last release that there is a new data type called 'scrp' for a
- list of data but it is subjected to change, well, it has been changed in this version.
- It is now replaced by 'list' with a different structure. We need not know about the
- exact structure. Rather you can call a CNVT to make a list. The paraminfo that you passed
- to the CNVT called ' MakeList' is
- ResType of first item in list
- handle to first item in list
- ResType of result, i.e 'list'
- handle to the list
- ResType of 2nd item in list
- handle to 2nd item in list
- ..
- ResType of Nth item in list
- handle to Nth item in list
-
- and parmCount is N.
-
- One problem with call by name is that it is not easily localizable. Procedure EnglishNameA
- may call procedure EnglishNameB. In France they are renamed FrenchNameA and FrenchNameB.
- However procedure A is still calling EnglishNameB in its code and hence it cannot be located.
- I had a clean solution in verison 0.62 but I have to removed it for other consideration.
- Now each resource is encouraged to be assigned an 8 byte name which will be the resource
- name of the CNV! resource and will be language independent. For reason that will be clear in
- the future, the first 4 byte of the 8 byte name should be 'MAGI', One resource should call another
- by the 8 byte name (using a resource type of 'CNV!') to avoid localization problem. The old
- method of calling by full name would still work.
-
- So to call another code resource with signature 'MAGIABCD'
-
- err := GoExec('CNV!', 'MAGIABCD', parmCount, useDefault, parmPtr, entryPoint);
-
- An important feature of version 0.64 is that any type of code resource may be used provided
- there is an adopter for it. The adopter is a CNVT called ' DoXXXX' where XXXX is the
- data type. So if you want to use XCMD, you need to have a CNVT called ' DoXCMD' that would
- translate CNVT calling convention to XCMD calling convention. ' DoXXXX' CNVT will get
- a parameter block with parmCount = 3, the first parameter is still the source data, and the
- second parameter is still for storing the result, the third parameter is a handle to the
- resource handle. So when you called 'TEXTFlash', the text is in the srcData, the Flash XCMD
- resource handle is in the third parameter, ' DoXCMD' would translate the text data into a
- zero terminated string that Flash expects, then it would lock down Flash and call it, then
- in the case of an XFCN, it would take the function result which is a zero terminated string
- and change it back to text and then put in back as the second parameter. This is how you can
- introduce new code resource type to CM.
-
- The Think Pascal shell program has been updated to reflect these changes.
-
- ------------------------------------------------------------------------------
-
- There is really no programming change in version 0.65. The ICONPICT.p example was found to
- be wrong so it is fixed now. Also if the user for some reason cancel in a CNVT, a err or -128
- should be returned (most of the supplied CNVTs are not doing that, that will be fixed in
- future.
-
-